package com.piggy.logi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.piggy.common.core.constant.SecurityConstants;
import com.piggy.common.core.domain.R;
import com.piggy.common.core.utils.FeignResultUtils;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.logi.common.datascope.annotation.LogiDataScope;
import com.piggy.logi.sys.api.domain.LogiSysDept;
import com.piggy.logi.sys.api.vo.LogiDeptLineExtVo;
import com.piggy.logi.sys.api.vo.LogiSysDeptExtVo;
import com.piggy.logi.sys.api.vo.LogiSysDeptVo;
import com.piggy.logi.sys.api.bo.LogiSysDeptExtCusEditBo;
import com.piggy.logi.sys.bo.LogiDeptLineQueryBo;
import com.piggy.logi.sys.bo.LogiSysDeptExtQueryBo;
import com.piggy.logi.sys.domain.LogiSysDeptExt;
import com.piggy.logi.sys.mapper.LogiSysDeptExtCusMapper;
import com.piggy.logi.sys.mapper.LogiSysDeptExtMapper;
import com.piggy.logi.sys.service.ILogiDeptLineService;
import com.piggy.logi.sys.service.ILogiSysDeptExtService;
import com.piggy.logi.sys.service.ILogiSysDeptService;
import com.piggy.sys.api.RemoteDistrictService;
import com.piggy.sys.api.vo.BaseAddressVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 部门扩展信息Service业务层处理
 *
 * @author piggy
 * @date 2023-08-10
 */
@Slf4j
@Service
public class LogiSysDeptExtServiceImpl extends ServiceImpl<LogiSysDeptExtMapper, LogiSysDeptExt> implements ILogiSysDeptExtService {

    @Resource
    private ILogiSysDeptService deptService;

    @Resource
    private LogiSysDeptExtCusMapper extCusMapper;

    @Resource
    private RemoteDistrictService districtService;

    @Resource
    private ILogiDeptLineService deptLineService;

    @Override
    public LogiSysDeptExtVo queryById(Long id) {
        LogiSysDeptExtVo vo = getVoById(id, LogiSysDeptExtVo.class);
        LogiSysDeptVo deptVo = deptService.getVoById(vo.getDeptId(), LogiSysDeptVo.class);
        LogiSysDeptExtVo vo1 = new LogiSysDeptExtVo();
        BeanUtil.copyProperties(deptVo, vo1, CopyOptions.create().ignoreNullValue());
        BeanUtil.copyProperties(vo, vo1, CopyOptions.create().ignoreNullValue());

        return Lists.newArrayList(vo1).get(0);
    }

    @Override
    public TableDataInfo<LogiSysDeptExtVo> queryPageList(LogiSysDeptExtQueryBo bo) {
        /*PagePlus<LogiSysDeptExt, LogiSysDeptExtVo> result = pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo), LogiSysDeptExtVo.class);
        return PageUtils.buildDataInfo(result);*/
        PageInfo<LogiSysDeptExtVo> result = PageHelper.startPage(bo.getPageNum(), bo.getPageSize()).doSelectPageInfo(() -> {
            List<LogiSysDeptExtVo> voList = extSysDeptList(bo);
            fillData(voList);
        });

        return PageUtils.buildDataInfo(result);

    }

    @Override
    public List<LogiSysDeptExtVo> queryList(LogiSysDeptExtQueryBo bo) {
        List<LogiSysDeptExtVo> voList = extSysDeptList(bo);
        return fillData(voList);
    }

    @Override
    public LogiSysDeptExtVo queryByDeptId(Long deptId) {
        LogiSysDeptExtVo vo = extCusMapper.getExtSysDeptByDeptId(deptId);
        if (ObjectUtil.isEmpty(vo)) {
            return vo;
        }
        return fillData(Lists.newArrayList(vo)).get(0);
    }

    private LambdaQueryWrapper<LogiSysDeptExt> buildQueryWrapper(LogiSysDeptExtQueryBo bo) {
        LambdaQueryWrapper<LogiSysDeptExt> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, LogiSysDeptExt::getId, bo.getId());
        lqw.eq(bo.getDeptId() != null, LogiSysDeptExt::getDeptId, bo.getDeptId());
        lqw.eq(StrUtil.isNotBlank(bo.getLegalIdcard()), LogiSysDeptExt::getLegalIdcard, bo.getLegalIdcard());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptPost()), LogiSysDeptExt::getDeptPost, bo.getDeptPost());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptNature()), LogiSysDeptExt::getDeptNature, bo.getDeptNature());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptIndustry()), LogiSysDeptExt::getDeptIndustry, bo.getDeptIndustry());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptEntType()), LogiSysDeptExt::getDeptEntType, bo.getDeptEntType());
        lqw.eq(bo.getDeptDate() != null, LogiSysDeptExt::getDeptDate, bo.getDeptDate());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptTel()), LogiSysDeptExt::getDeptTel, bo.getDeptTel());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptLicense()), LogiSysDeptExt::getDeptLicense, bo.getDeptLicense());
        lqw.eq(bo.getDeptProv() != null, LogiSysDeptExt::getDeptProv, bo.getDeptProv());
        lqw.eq(bo.getDeptCity() != null, LogiSysDeptExt::getDeptCity, bo.getDeptCity());
        lqw.eq(bo.getDeptDistrict() != null, LogiSysDeptExt::getDeptDistrict, bo.getDeptDistrict());
        lqw.eq(StrUtil.isNotBlank(bo.getDeptAddress()), LogiSysDeptExt::getDeptAddress, bo.getDeptAddress());
        lqw.eq(bo.getVehicleNum() != null, LogiSysDeptExt::getVehicleNum, bo.getVehicleNum());
        lqw.eq(bo.getStaffNum() != null, LogiSysDeptExt::getStaffNum, bo.getStaffNum());
        lqw.eq(bo.getQuliFlag() != null, LogiSysDeptExt::getQuliFlag, bo.getQuliFlag());
        lqw.eq(bo.getQuliTime() != null, LogiSysDeptExt::getQuliTime, bo.getQuliTime());
        return lqw;
    }

    @Override
    @LogiDataScope(deptAlias = "d")
    public List<LogiSysDeptExtVo> extSysDeptList(LogiSysDeptExtQueryBo bo) {
        return extCusMapper.extSysDeptList(bo);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public LogiSysDeptExtVo insertByAddBo(LogiSysDeptExtCusEditBo bo) {
        LogiSysDeptExt add = BeanUtil.toBean(bo, LogiSysDeptExt.class);
        if (ObjectUtil.isNotEmpty(add.getDeptId())) {
            LogiSysDeptExtVo dept = deptService.selectDeptById(add.getDeptId());
            BeanUtil.copyProperties(BeanUtil.toBean(bo, LogiSysDept.class), dept, CopyOptions.create().ignoreNullValue());
            deptService.updateDept(BeanUtil.toBean(dept, LogiSysDept.class));

            LogiSysDeptExt ext = getByDeptId(add.getDeptId());
            if (ObjectUtil.isNotEmpty(ext)) {
                BeanUtil.copyProperties(bo, ext, CopyOptions.create().ignoreNullValue());
                ext.setUpdateTime(new Date());
                baseMapper.updateById(ext);
                return queryById(ext.getId());
            }
        } else {
            LogiSysDept dept = BeanUtil.toBean(bo, LogiSysDept.class);
            dept.setParentId(bo.getParentId());
            dept.setCreateBy(bo.getCreateBy());
            dept.setCreateTime(new Date());
            deptService.insertDept(dept);
            // 设置部门id
            add.setDeptId(dept.getDeptId());
        }

        add.setCreateTime(new Date());
        save(add);

        if (CollUtil.isNotEmpty(bo.getDeptLineList())) {
            deptLineService.batchByAddBo(bo.getDeptLineList());
        }
        return queryById(add.getId());
    }

    private LogiSysDeptExt getByDeptId(Long deptId) {
        return baseMapper.selectOne(new LambdaQueryWrapper<LogiSysDeptExt>().eq(LogiSysDeptExt::getDeptId, deptId));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public LogiSysDeptExtVo updateByEditBo(LogiSysDeptExtCusEditBo bo) {
        LogiSysDeptExt update = BeanUtil.toBean(bo, LogiSysDeptExt.class);
        LogiSysDept dept = BeanUtil.toBean(bo, LogiSysDept.class);
        deptService.updateDept(dept);
        if (ObjectUtil.isEmpty(bo.getId())) {
            LogiSysDeptExt ext = getByDeptId(dept.getDeptId());
            if (ObjectUtil.isNotEmpty(ext)) {
                update.setId(ext.getId());
            }
        }

        if (ObjectUtil.isNotEmpty(update.getId())) {
            this.updateById(update);
        }
        else {
            this.baseMapper.insert(update);
        }

        //if (CollUtil.isNotEmpty(bo.getDeptLineList())) {
            deptLineService.batchByUpdateBo(bo.getDeptLineList(), bo.getDeptId());
        //}

        return queryById(update.getId());

    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    private List<LogiSysDeptExtVo> fillData(List<LogiSysDeptExtVo> extVos) {
        extVos.stream().peek(vo -> {
            if (ObjectUtil.isEmpty(vo)) {
                return;
            }
            R<BaseAddressVo> addressVoR = districtService.getDistrictVo(ObjectUtil.defaultIfNull(vo.getDeptDistrict(), 0L).toString(), SecurityConstants.INNER);
            FeignResultUtils.throwIfFailed(addressVoR);
            BaseAddressVo addressVo = addressVoR.getData();
            if (ObjectUtil.isNotEmpty(addressVo)) {
                vo.setDeptDistrictName(addressVo.getProvName() + addressVo.getCityName() + addressVo.getDistName());
            }
            vo.setLineList(deptLineService.queryList(new LogiDeptLineQueryBo().setMainDeptId(vo.getDeptId())));
        }).collect(Collectors.toList());
        return extVos;
    }
}
